package orchestration.android.execution.tasks;

import java.util.HashMap;
import java.util.Map;

/**
 * @author  <a href="mailto:car.ferrarini@gmail.com">Carlo Ferrarini</a>
 */
public class AidlFile {
	/**
	 * @uml.property  name="packageName"
	 */
	private String packageName;
	/**
	 * @uml.property  name="interfaceName"
	 */
	private String interfaceName;
	/** 
	 * @uml.property name="methods"
	 */
	private Map<String,AidlMethod> methods;
	
	
	/**
	 * @return
	 * @uml.property  name="packageName"
	 */
	public String getPackageName() {
		return packageName;
	}
	/**
	 * @param packageName
	 * @uml.property  name="packageName"
	 */
	public void setPackageName(String packageName) {
		this.packageName = packageName;
	}
	/**
	 * @return
	 * @uml.property  name="interfaceName"
	 */
	public String getInterfaceName() {
		return interfaceName;
	}
	/**
	 * @param interfaceName
	 * @uml.property  name="interfaceName"
	 */
	public void setInterfaceName(String interfaceName) {
		this.interfaceName = interfaceName;
	}
	/** 
	 * @return
	 * @uml.property  name="methods"
	 */
	public Map<String,AidlMethod> getMethods() {
		return methods;
	}
	public String getDescriptor() {
		return packageName+"."+interfaceName;
	}
	public int getMethodId(String methodName) {
		return methods.get(methodName).getId();
	}
	
	
	public static AidlFile parse(String aidl){
		AidlFile result= new AidlFile();
		Map<String,AidlMethod> methods= new HashMap<String, AidlMethod>();
		//remove				/*...*/ comments				//... comments			  lineBreaks		multiple whitespaces
		aidl= aidl.replaceAll("/\\*.*\\*/", "").replaceAll("//.*\\n", "\\n").replaceAll("\\n", ""); //.replaceAll("[\\s]+","\\s");
		String[] splitted= aidl.split("\\{");
		String[] headStatements=splitted[0].split(";");
		String methodStatements=splitted[1];
		result.setPackageName(headStatements[0].split(" ")[1]);
		String[] interfaceDeclarationLineTokens=headStatements[headStatements.length-1].split(" ");
		if (interfaceDeclarationLineTokens.length==2) {
			result.setInterfaceName(interfaceDeclarationLineTokens[1]);
		}else if(interfaceDeclarationLineTokens.length==3){//XXX oneway interfaces are treated as normal ones
			result.setInterfaceName(interfaceDeclarationLineTokens[2]);
		}
		methodStatements=methodStatements.substring(0, methodStatements.lastIndexOf("}")-1);//remove everything after "}"
		int methodId=0;
		for(String line : methodStatements.split(";")){
			AidlMethod method= AidlMethod.parse(line);
			method.setId(methodId);
			methodId++;
			methods.put(method.getName(), method);
		}
		result.setMethods(methods);
		return result;
	}
	/** 
	 * @param methods
	 * @uml.property  name="methods"
	 */
	public void setMethods(Map<String,AidlMethod> methods) {
		this.methods = methods;
	}
}
